import { defineComponent, ref, nextTick, onUpdated, onMounted } from "vue"
import { createNamespace } from "../../util/create"
import { Loading as VanLoading} from 'vant'
import { useScrollParent } from '../../hooks/useScrollParent'
import { useRect } from '../../hooks/useRect'
import { useEventListener } from '../../hooks/useEventListener'
import './OpList.scss'

const [name, bem] = createNamespace('list')

export default defineComponent({
    name,
    props: {
        offset: { // 滚动条与底部距离小于offset时触发load事件
            type: Number,
            default: 300
        },
        direction: { // 加载方向
            type: String,
            default: 'down'
        },
        loading: {
            type: Boolean
        },
        finished: { // 是否加载完成
            type: Boolean
        },
        finishedText: {
            type: String
        },
        loadingText: {
            type: String
        }
    },
    /**
     * setup()函数是在beforeCreate钩子之前执行的一个函数
     * @param props 一个响应式的对象，包含了从父组件中传过来的所有属性。不能使用 ES6 解构
     * @param context 上下文对象，暴露了其它可能在 setup 中有用的值。能使用 ES6 解构
     */
    setup(props, { slots, emit }) {
        const loading = ref(props.loading)
        const root = ref()
        const placeholder = ref()
        const scrollParent = useScrollParent(root)

        const check = () => {
            nextTick(() => {
                if (loading.value || props.finished) {
                    return
                }
                const scrollParentRect = useRect(scrollParent)
                if (!scrollParentRect.height) {
                    return
                }
                const { offset, direction } = props
                let isReachEdge = false
                isReachEdge = scrollParentRect.top <= offset

                if (isReachEdge) {
                    loading.value = true
                    emit('update:loading', true)
                    emit('load')
                }
            })
        }

        const renderLoading = () => {
            if (loading.value && !props.finished) {
                return (
                    <div class={bem('loading')}>{
                        <VanLoading class={bem('loading-icon')}>{props.loadingText || '加载中'}</VanLoading>
                    }</div>
                )
            }
        }

        const renderFinishedText = () => {
            if (props.finished) {
                if (props.finishedText) {
                    return <div class={bem('finished-text')}>{props.finishedText}</div>
                }
            }
        }

        onUpdated(() => {
            loading.value = props.loading
        })
    
        onMounted(() => {
            check()
        })
    
        useEventListener('scroll', check, {
            target: scrollParent,
            passive: true,
        })
        
        return () => {
            const Content = slots.default?.(); // 默认插槽内容

            return (
                <div ref={root} class={bem()}>
                    {Content}
                    {renderLoading()}
                    {renderFinishedText()}
                </div>
            )
        }
    }
})